﻿#pragma once
#ifndef SessionMgr_hpp
#define SessionMgr_hpp

#include<memory>
#include<string>
#include<map>
#include<unordered_set>
#include<vector>
#include<unordered_map>
#include<functional>

#include"../Base/Concurrency/Mutex.hpp"
#include"../Base/Concurrency/Lock.hpp"
#include"../Base/Network/NetworkDef.hpp"


namespace MMFNetwork
{
    //前置声明
    class Session;
}

namespace SC_SUN
{

    class SessionMgr
    {
        //所有的sesstion
        //std::unordered_map<std::string, std::shared_ptr<MMFNetwork::Session>> mSessions;
        //std::unordered_map<std::shared_ptr<MMFNetwork::Session>, std::string> mSessionsToIp;
        std::vector<std::shared_ptr<MMFNetwork::Session>> mSessions;

        //对 session与类型之间的关 系进行管理
        std::unordered_map<int, std::unordered_set<std::shared_ptr<MMFNetwork::Session>>> mTypeToSessions;
        std::unordered_map<std::shared_ptr<MMFNetwork::Session>, int> mSessionsToType;

        //互斥锁
        MMF::Mutex mMutex;

        //是否每个类型只能有一个session
        bool mOnlyOnePerType;

        //各种时机的回调函数
        std::function<void(const std::shared_ptr<MMFNetwork::Session>&)> mSessionAddedCallback;
        std::function<void(const std::shared_ptr<MMFNetwork::Session>&)> mSssionDeleteCallback;
        std::function<void(const std::shared_ptr<MMFNetwork::Session>&, int)> mSessionTypedCallback;
        std::function<void(const std::shared_ptr<MMFNetwork::Session>&, int)> mSessionDeTypedCallback;

    public:

        SessionMgr();
        ~SessionMgr();

        bool AddSession(const std::shared_ptr<MMFNetwork::Session>& session);
        void SetSessionAddedCallback(std::function<void(const std::shared_ptr<MMFNetwork::Session>&)>);
        bool DelSession(const std::shared_ptr<MMFNetwork::Session>& session);
        void SetSessionDeleteCallback(std::function<void(const std::shared_ptr<MMFNetwork::Session>&)>);

        bool Type(int type, const std::shared_ptr<MMFNetwork::Session>& session);
        void SetSessionTypedCallback(std::function<void(const std::shared_ptr<MMFNetwork::Session>&, int)>);
        void DeType(int type, const std::shared_ptr<MMFNetwork::Session>& session);
        void DeType(const std::shared_ptr<MMFNetwork::Session>& session);
        void SetSessionDeTypedCallback(std::function<void(const std::shared_ptr<MMFNetwork::Session>&, int)>);
        void SendToType(int type, void* msg, uint32_t msgLen);

        void SendToAll(void* msg, uint32_t msgLen);
        void AsyncSendToAll(void* msg, uint32_t msgLen);

        void OnlyOnePerType();
    };
}


#endif